<!--
 * @Description:
 * @Author 卞鹏飞 <228443632@qq.com>
 * @create 23/11/24 PM1:05
 -->
<!--setup-->
<script setup lang="ts">
import { onMounted, getCurrentInstance, ref, type ComponentInternalInstance, computed } from 'vue'
import { initSharedProps } from '@/components/biz-micro-view/micro-app/shared'
import useUserStore from '@store/use-user-store.ts'
import useAppStore from '@store/use-app-store.ts'
import useMenuStore from '@store/use-menu-store.ts'
import useLayoutStore from '@store/use-layout-store.ts'
import { usePostmateParent } from './use-postmate-parent.ts'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
  cache,
  isArray,
  isFunction,
  isPlainObject,
  isString,
  parseJsonNoError,
  stringPathJoin,
  stringifyURL
} from 'sf-utils2'
import { useRouterPlus } from '@/router/use-router-plus.ts'
import { propsInfo } from '@/components/biz-micro-iframe/types.ts'
import setting from '@/setting.ts'
import { raf } from '@shared/utils/dom'

const { proxy } = getCurrentInstance() as ComponentInternalInstance

const props = defineProps({
  ...propsInfo
})
const emit = defineEmits<{ (e: 'load'): void }>()

/* 状态 */
const loading = ref(true)
const userStore = useUserStore()
const menusStore = useMenuStore()
const appStore = useAppStore()
const layoutStore = useLayoutStore()
const { router, route } = useRouterPlus()

const hashSign = '____'

const PLATFORM = setting.platform

const tabKey = route.fullPath
// ||
// profile.cfDisposalAddress + `/#/authorization/cf-manage` ||
// profile.cfWorkflowAddress + `/#/authorization/cf-manage`

console.log('props', props)

const containerRef = ref<HTMLHtmlElement>()
const parentPostmate = ref({
  url: computed(() => {
    if (/^https?/.test(props.entry)) {
      return props.entry
    }

    // console.log('decodeURIComponent(decodeURIComponent(props.entry)).replace(\'#\', hashSign)', decodeURIComponent(decodeURIComponent(props.entry)).replace('#', hashSign))
    // const entryDecode = encodeURIComponent(decodeURIComponent(decodeURIComponent(props.entry)))
    return (
      (stringifyURL(props?.entryBasePrefix.replace('#', hashSign), {
        redirectUri: decodeURIComponent(decodeURIComponent(props.entry)).replace('#', hashSign),
        autoUpdateTabTitle: Number(props.autoUpdateTabTitle),
        htmlLoading: 0,
        platform: PLATFORM
      }) as string) || ''
    ).replace(hashSign, '#')
  }),
  onload: () => {
    loading.value = false
    emit('load')
  }
})
const { onParentPostmateMounted, childHandshake, destroy, msgId: uid } = usePostmateParent(containerRef, parentPostmate)

/* 方法 */

onParentPostmateMounted(async (child) => {
  /**
   * 初始化生成数据
   */
  async function initInnerData() {
    const innerProps = initSharedProps({ entry: props.entry }) as any

    delete innerProps.shared

    delete innerProps.assertRouteNextTo
    innerProps.shared ||= {
      store: {}
    }

    // app
    innerProps.shared.store.app = {
      publicIp: appStore?.publicIp
    }

    // 用户信息
    innerProps.shared.store.user = {
      userInfo: { ...userStore.userInfo, ...(props.mountedData || {}) },
      token: userStore.token
    }

    // 菜单
    innerProps.shared.store.menus = {
      menuData: { ...menusStore.menuData }
    }

    // 字典
    innerProps.shared.DICT = cache.getItem('DICT')
    innerProps.shared.PARAM = cache.getItem('PARAM')

    // 挂载之前 hooks
    if (isFunction(props.beforeMountedDataHook)) {
      await props.beforeMountedDataHook(innerProps)
    }

    return innerProps
  }

  // 挂载，父传子
  child.call('mounted', JSON.stringify(await initInnerData()))

  /** **********挂载，子传父************ */
  // 挂载成功
  child.on('mounted', ({ msgId }) => {
    // eslint-disable-next-line no-useless-return
    if (uid.value != msgId) return
    //
  })

  // 卸载成功
  child.on('unmounted', ({ msgId }) => {
    // eslint-disable-next-line no-useless-return
    if (uid.value != msgId) return
    //
  })

  // 退出登录
  child.on('loginOut', () => {
    userStore.loginOut()
  })

  // 路由监听
  child.on('routerMethod', ({ msgId, data }) => {
    if (uid.value != msgId) return
    const methodName = data?.methodName
    const fn = router[methodName]
    if (isFunction(fn)) {
      switch (methodName) {
        case 'push':
        case 'replace': {
          const [$0] = data?.args || []
          if (isString($0)) {
            // 字符串
            return fn.call(router, stringPathJoin(_curRouteBase.value, $0))
          }
          if (isPlainObject($0)) {
            // 普通js对象
            $0.path = stringPathJoin(_curRouteBase.value, $0.path)
            return fn.call(router, ...(data?.args || []))
          }
          break
        }
        case 'closeTab': {
          const args = data?.args || []

          if (!args[0]) {
            let { targetTab } = layoutStore.getActiveTabInfo()
            args[0] = targetTab?.key
          }
          // @ts-expect-error
          raf(() => {
            fn.call(router, ...(args || []))
          })
          break
        }
        default: {
          return fn.call(router, ...(data?.args || []))
        }
      }
    }
  })

  // 退出登录
  child.on('elMessage', ({ msgId, data }) => {
    if (uid.value != msgId) return
    console.log('data', data)
    const fn = ElMessage[data?.methodName]
    if (isFunction(fn)) {
      fn.call(this, ...(data?.args || []))
    }
  })

  /** **********挂载，父传子************ */
  // 更新tabs
  child.on('updateTab', ({ msgId, data }) => {
    if (uid.value != msgId) return
    layoutStore.updateTab({
      key: data?.key || tabKey,
      ...(data || {})
    })
  })

  // 更新tabs
  child.on('closeTab', ({ msgId, data }) => {
    if (uid.value != msgId) return
    // const opts || { autoJump: false }
    router.closeTab(data?.key || tabKey, data?.options)
  })

  // 显示退出登录弹框
  child.on('openLoginOut', ({ msgId, data }) => {
    if (uid.value != msgId) return
    const eventData = parseJsonNoError(data) || {}
    ElMessageBox.alert(eventData?.message, eventData?.title || '提示', {
      type: 'error',
      confirmButtonText: '确定',
      callback: async () => {
        await userStore.loginOut()
        router.push('/login')
        window.location.reload()
      }
    })
  })
})

/**
 * 初始化
 */
const init = () => {}

/* 计算 */

/**
 * 当前路由前缀
 */
const _curRouteBase = computed(() => {
  const pathMatch = (route.params?.pathMatch || []) as string[]
  if (isArray(pathMatch)) {
    const paramsPath = stringPathJoin('/', pathMatch.join('/'))
    return route.path.replace(paramsPath, '')
  }
  return ''
})

/* 监听 */

/* 周期 */
onMounted(() => {
  init()
})

/* 暴露 */
defineExpose({
  $: proxy.$,
  childHandshake,
  destroy
})
</script>

<!--render-->
<template>
  <div
    v-spin="{
      loading,
      showLoadingText: true,
      loadingText: `页面正在加载中... `,
      isFakeProgressText: true,
      mask: false,
      type: 'circle2'
    }"
    class="easy-iframe"
  >
    <div
      ref="containerRef"
      class="absolute left-0 top-0 h-full w-full"
    />
  </div>
</template>

<!--style-->
<style scoped lang="less">
.easy-iframe {
  position: relative;
  display: flex;
  width: 100%;
  height: 100%;
  flex-direction: column;
  flex: 1;
}
</style>
